<?php
namespace app\common\util;

class Util
{
    /**
     * 将一个字符串部分字符用$re替代隐藏
     * @param string $string 待处理的字符串
     * @param int $start 规定在字符串的何处开始，
     *                            正数 - 在字符串的指定位置开始
     *                            负数 - 在从字符串结尾的指定位置开始
     *                            0 - 在字符串中的第一个字符处开始
     * @param int $length 可选。规定要隐藏的字符串长度。默认是直到字符串的结尾。
     *                            正数 - 从 start 参数所在的位置隐藏
     *                            负数 - 从字符串末端隐藏
     * @param string $re 替代符
     * @return string   处理后的字符串
     */
    public static function hidestr($string, $start = 0, $length = 0, $re = '*')
    {
        if (empty($string)) return false;
        $strarr = array();
        $mb_strlen = mb_strlen($string);
        while ($mb_strlen) {
            $strarr[] = mb_substr($string, 0, 1, 'utf8');
            $string = mb_substr($string, 1, $mb_strlen, 'utf8');
            $mb_strlen = mb_strlen($string);
        }
        $strlen = count($strarr);
        $begin = $start >= 0 ? $start : ($strlen - abs($start));
        $end = $last = $strlen - 1;
        if ($length > 0) {
            $end = $begin + $length - 1;
        } elseif ($length < 0) {
            $end -= abs($length);
        }
        for ($i = $begin; $i <= $end; $i++) {
            $strarr[$i] = $re;
        }
        if ($begin >= $end || $begin >= $last || $end > $last) return false;
        return implode('', $strarr);
    }

    /**
     * 验证手机号是否正确
     * @param number $mobile
     */
    public static function is_mobile($mobile)
    {
        if (!is_numeric($mobile)) {
            return false;
        }
        return preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^17[0,6,7,8]{1}\d{8}$|^18[\d]{9}$#', $mobile) ? true : false;
    }

    public static function curl_get($url)
    {
        $ch = curl_init();
        $header = "Accept-Charset: utf-8";

//        if (class_exists ( '\CURLFile' )) {//php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默认值不同
//            curl_setopt ($url, CURLOPT_SAFE_UPLOAD, true);
//        } else {
//            if (defined ( 'CURLOPT_SAFE_UPLOAD' )) {
//                curl_setopt ( $url, CURLOPT_SAFE_UPLOAD, false );
//            }
//        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
//    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($ch);
        return $temp;
    }

    /**
     * 七牛云图片地址
     * @param number $mobile
     */
    public static function qiniu_url($url)
    {
        $domain = \think\Config::get('qiniu.domain');
        return 'http://' . $domain . '/' . $url;
    }

    /**
     * 七牛云缩略图片地址
     * @param number $mobile
     */
    public static function small_qiniu_url($url, $width = '', $height = '')
    {
        if (empty($width)) {
            $width = \think\Config::get('qiniu.width');
        } else {
            $width = intval($width);
        }
        if (empty($height)) {
            $height = \think\Config::get('qiniu.height');
        } else {
            $height = intval($height);
        }
        return $url . '?imageView2/1/w/' . $width . '/h/' . $height;
    }

    public static function custom_url_path($url)
    {
        if (preg_match('/^http:/', $url) == 0) {
            return 'http://' . request()->server('HTTP_HOST') . $url;
        } else {
            return $url;
        }
    }

    /**
     * 简单对称加密算法之加密
     * @param String $string 需要加密的字串
     * @param String $skey 加密EKY
     * @author Anyon Zou <zoujingli@qq.com>
     * @date 2013-08-13 19:30
     * @update 2014-10-10 10:10
     * @return String
     */
    public static function tel_encode($string = '')
    {
        $strArr = str_split(base64_encode($string));
        $strCount = count($strArr);
        $encode = db('system_config')->where(['name' => 'SYSTEM_TEL_ENCODE'])->field('value')->find();
        foreach (str_split($encode['value']) as $key => $value)
            $key < $strCount && $strArr[$key] .= $value;
        return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join('', $strArr));
    }

    /**
     * 简单对称加密算法之解密
     * @param String $string 需要解密的字串
     * @param String $skey 解密KEY
     * @author Anyon Zou <zoujingli@qq.com>
     * @date 2013-08-13 19:30
     * @update 2014-10-10 10:10
     * @return String
     */
    public static function tel_decode($string = '')
    {
        $strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
        $strCount = count($strArr);
        $encode = db('system_config')->where(['name' => 'SYSTEM_TEL_ENCODE'])->value('value');
        foreach (str_split($encode) as $key => $value)
            $key <= $strCount && $strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
        return base64_decode(join('', $strArr));
    }

    /**
     * 把数组转为对象
     * @param $array
     * @return StdClass
     */
    public static function array_to_object($array)
    {
        if (is_array($array)) {
            $obj = new \stdClass();
            foreach ($array as $key => $val) {
                $obj->$key = $val;
            }
        } else {
            $obj = $array;
        }
        return $obj;
    }

    /**
     * 把对象转为数组
     * @param $object
     * @return mixed
     */
    public static function object_to_array($object)
    {
        if (is_object($object)) {
            foreach ($object as $key => $value) {
                $array[$key] = $value;
            }
        } else {
            $array = $object;
        }
        return $array;
    }

    /**
     * 获得IP地址的中文信息
     * @param bool $ip 要查询的IP地址，如果为空就获得本地地址
     * @return array
     */
    public static function get_ip_info($ip)
    {

        $ip2region = new \Ip2Region();
        $info = $ip2region->btreeSearch($ip);

        $add_info = explode('|', $info['region']);

        return $add_info;
    }

    /**
     * 添加http
     * @param $url
     * @return string
     */
    public static function http_url_path($url)
    {
        if (preg_match('/^http:/', $url) == 0) {
            if ('edu.dms.kh888.cn' == $url) {
                return 'http://'. $url;
            } else {
                return 'https://'. $url;
            }
        } else {
            return $url;
        }
    }

    public static function unparse_url($parsed_url)
    {
        $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
        $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
        $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
        $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
        $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
        $pass = ($user || $pass) ? "$pass@" : '';
        $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
        $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
        $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
        return "$scheme$user$pass$host$port$path$query$fragment";
    }

    /**
     * 获取错误原因
     * @param $code
     * @return mixed
     */
    public static function get_error($code)
    {
        $error_msg = [
            '-1' => '系统繁忙',
            '0' => '请求成功',
            '40001' => '获取access_token时AppSecret错误，或者access_token无效',
            '40002' => '不合法的凭证类型',
            '40003' => '不合法的OpenID',
            '40004' => '不合法的媒体文件类型',
            '40005' => '不合法的文件类型',
            '40006' => '不合法的文件大小',
            '40007' => '不合法的媒体文件id',
            '40008' => '不合法的消息类型',
            '40009' => '不合法的图片文件大小',
            '40010' => '不合法的语音文件大小',
            '40011' => '不合法的视频文件大小',
            '40012' => '不合法的缩略图文件大小',
            '40013' => '不合法的APPID',
            '40014' => '不合法的access_token',
            '40015' => '不合法的菜单类型',
            '40016' => '不合法的按钮个数',
            '40017' => '不合法的按钮个数',
            '40018' => '不合法的按钮名字长度',
            '40019' => '不合法的按钮KEY长度',
            '40020' => '不合法的按钮URL长度',
            '40021' => '不合法的菜单版本号',
            '40022' => '不合法的子菜单级数',
            '40023' => '不合法的子菜单按钮个数',
            '40024' => '不合法的子菜单按钮类型',
            '40025' => '不合法的子菜单按钮名字长度',
            '40026' => '不合法的子菜单按钮KEY长度',
            '40027' => '不合法的子菜单按钮URL长度',
            '40028' => '不合法的自定义菜单使用用户',
            '40029' => '不合法的oauth_code',
            '40030' => '不合法的refresh_token',
            '40031' => '不合法的openid列表',
            '40032' => '不合法的openid列表长度',
            '40033' => '不合法的请求字符，不能包含\uxxxx格式的字符',
            '40035' => '不合法的参数',
            '40038' => '不合法的请求格式',
            '40039' => '不合法的URL长度',
            '40050' => '不合法的分组id',
            '40051' => '分组名字不合法',
            '41001' => '缺少access_token参数',
            '41002' => '缺少appid参数',
            '41003' => '缺少refresh_token参数',
            '41004' => '缺少secret参数',
            '41005' => '缺少多媒体文件数据',
            '41006' => '缺少media_id参数',
            '41007' => '缺少子菜单数据',
            '41008' => '缺少oauth code',
            '41009' => '缺少openid',
            '42001' => 'access_token超时',
            '42002' => 'refresh_token超时',
            '42003' => 'oauth_code超时',
            '43001' => '需要GET请求',
            '43002' => '需要POST请求',
            '43003' => '需要HTTPS请求',
            '43004' => '需要接收者关注',
            '43005' => '需要好友关系',
            '44001' => '多媒体文件为空',
            '44002' => 'POST的数据包为空',
            '44003' => '图文消息内容为空',
            '44004' => '文本消息内容为空',
            '45001' => '多媒体文件大小超过限制',
            '45002' => '消息内容超过限制',
            '45003' => '标题字段超过限制',
            '45004' => '描述字段超过限制',
            '45005' => '链接字段超过限制',
            '45006' => '图片链接字段超过限制',
            '45007' => '语音播放时间超过限制',
            '45008' => '图文消息超过限制',
            '45009' => '接口调用超过限制',
            '45010' => '创建菜单个数超过限制',
            '45015' => '回复时间超过限制',
            '45016' => '系统分组，不允许修改',
            '45017' => '分组名字过长',
            '45018' => '分组数量超过上限',
            '46001' => '不存在媒体数据',
            '46002' => '不存在的菜单版本',
            '46003' => '不存在的菜单数据',
            '46004' => '不存在的用户',
            '47001' => '解析JSON/XML内容错误',
            '48001' => 'api功能未授权',
            '50001' => '用户未授权该api',
        ];
        return $error_msg[$code];
    }

    public static function get_url($sid)
    {
        $store = db('store')->where(['store_id' => $sid])->field('domain')->find();
        $host = $store['domain'] == '' ? $_SERVER['HTTP_HOST'] : $store['domain'];
        $host = self::http_url_path($host);
        $url = [
            '0' => [
                'url' => $host . '/m/html/dmshelper.html?sid=' . $sid,
                'name' => '顾问中心'
            ],
            '1' => [
                'url' => $host . '/m/html/dmsedu.html?sid=' . $sid,
                'name' => '学员中心'
            ],
//            '2' => [
//                'url' => $host . '/m/html/dmsedu.html?sid=' . $sid . '&escape=attend',
//                'name' => '试听课程'
//            ],
            '2' => [
                'url' => $host . '/m/html/dmscommon.html?sid=' . $sid . '&escape=main.course',
                'name' => '课程商城'
            ],
            '3' => [
                'url' => $host . '/index.html',
                'name' => '首页'
            ],
            '4' => [
                'url' => $host . '/m/html/dmshelper.html?sid=' . $sid . '&escape=course',
                'name' => '营销课堂'
            ],
            '5' => [
                'url' => $host . '/m/html/dmshelper.html?sid=' . $sid . '&escape=statis.one',
                'name' => '课程签到报表'
            ],
            '6' => [
                'url' => $host . '/m/html/dmscommon.html?sid=' . $sid . '&escape=courseList',
                'name' => '课程海报'
            ],
            '7' => [
                'url' => $host . '/m/html/dmscommon.html?sid=' . $sid . '&escape=reports.courseList',
                'name' => '推送统计'
            ],
            '8' => [
                'url' => $host . '/m/html/dmscommon.html?sid=' . $sid . '&escape=poster',
                'name' => '活动海报'
            ],
            '9' => [
                'url' => $host . '/m/html/info_complete.html?sid=' . $sid,
                'name' => '完善资料'
            ],
            '10' => [
                'url' => '',
                'name' => '自定义链接'
            ],
        ];
        return $url;
    }


    /**
     * 把返回的数据集转换成Tree
     * @param array $list 要转换的数据集
     * @param string $pid parent标记字段
     * @param string $level level标记字段
     * @return array
     */
    public static function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0, $current_url = '')
    {
        // 创建Tree
        $tree = array();
        if (is_array($list)) {
            // 创建基于主键的数组引用
            $refer = array();
            foreach ($list as $key => $data) {
//                if (strtolower($data['url'])==strtolower($current_url)) {
//                    $list[$key]['class'] = 'active';
//                }
                $refer[$data[$pk]] = &$list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[] = &$list[$key];
                } else {
                    if (isset($refer[$parentId])) {
                        $parent = &$refer[$parentId];
                        $parent[$child][] = &$list[$key];
                    }
                }
            }
        }
        return $tree;
    }

    public static function json_name($str)
    {
        return self::emoji_encode($str);
    }

    public static function emoji_encode($nickname){
        $strEncode = '';
        $length = mb_strlen($nickname,'utf-8');
        for ($i=0; $i < $length; $i++) {
            $_tmpStr = mb_substr($nickname,$i,1,'utf-8');
            if(strlen($_tmpStr) >= 4){
                //$strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
            }else{
                $strEncode .= $_tmpStr;
            }
        }
        return $strEncode;
    }


    /**
     * 指定位置插入字符串
     * @param $str  原字符串
     * @param $i    插入位置
     * @param $substr 插入字符串
     * @return string 处理后的字符串
     */
    public static function insertToStr($str, $i, $substr){
        //指定插入位置前的字符串
        $startstr="";
        for($j=0; $j<$i; $j++){
            $startstr .= $str[$j];
        }

        //指定插入位置后的字符串
        $laststr="";
        for ($j=$i; $j<strlen($str); $j++){
            $laststr .= $str[$j];
        }

        //将插入位置前，要插入的，插入位置后三个字符串拼接起来
        $str = $startstr . $substr . $laststr;

        //返回结果
        return $str;
    }


    /**
     * 反序列化字符串
     * @param $str
     * @return mixed
     */
    public static function unserializeStr($str){
        //如果为json字符串则json解码
        if(self::isJson($str)){
            return json_decode($str, 1);
        }

        //unserialize():Error at offset
        //当我们取出数据库编码为GBK等中文编码，后又用转码函数转成UTF8后，再用unserialize函数时，因为中文在不同编码下的长度不同，就会出现这个问题了。
        //解决方案1：unserialize(preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $string))
        //解决方案2：由于php的原因，/e 模式存在漏洞，所以php5.5以后取消了这样的用法
        //preg_replace_callback('#s:(\d+):"(.*?)";#s',function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';},$data);
        $temp = preg_replace_callback('#s:(\d+):"(.*?)";#s',function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';}, $str);
        return unserialize($temp);
    }

    public static function isJson($str){
        json_decode($str);
        return (json_last_error() == JSON_ERROR_NONE);
    }


    /**
     * 序列化字符串 后期可能会做更改
     * @param $str
     * @return string
     */
    public static function serializeStr($str){
//        return serialize($str);
        return json_encode($str, JSON_UNESCAPED_UNICODE);
    }


    /**
     * 用户动态时间转换
     * @param $timestap
     * @return bool|string
     */
    public static function userDynamicTimeToStr($timestap){
        //当前时间戳
        $current_timestap = time();
        if($timestap > $current_timestap){
            return false;
        }

        //今天开始时间戳
        $today_begin_timestap = strtotime(date('Y-m-d', $current_timestap));

        //一小时前时间戳
        $latest_hour_timestap = $current_timestap - 60 * 60;

        //今天内
        if($timestap >= $today_begin_timestap){
            if($timestap > $latest_hour_timestap){
                //小于60s
                if($current_timestap - $timestap < 60){
                    $str = '刚刚';
                } else {
                    $minutes_before = ceil(($current_timestap - $timestap) / 60);
                    $str = $minutes_before.'分钟前';
                }
            } else {
                $hours_before = ceil(($current_timestap - $timestap) / 3600);
                $str = $hours_before.'小时前';
            }
        } else {
            $str = date('Y年m月d日', $timestap);
        }

        return $str;
    }

    public static function getImgSrcFromStr($str){
        $pattern="/<img.*?src=\"(.*?)\".*?>/is";
        preg_match_all($pattern,$str,$matches);
        return $matches[1];
    }

    public static function createQRcode($savePath, $qrData = 'PHP QR Code :)', $qrLevel = 'L', $qrSize = 4, $savePrefix = 'qrcode', $new = false){
        if (!isset($savePath)) return '';
        //设置生成png图片的路径
        $PNG_TEMP_DIR = $savePath;

        //检测并创建生成文件夹
        if (!file_exists($PNG_TEMP_DIR)) {
            mkdir($PNG_TEMP_DIR);
        }

        $filename = $PNG_TEMP_DIR . DS . 'qrcode.png';
        if(!$new){
            if (file_exists($filename)){
                return $filename;
            }
        }

        $errorCorrectionLevel = 'L';
        if (isset($qrLevel) && in_array($qrLevel, ['L', 'M', 'Q', 'H'])) {
            $errorCorrectionLevel = $qrLevel;
        }
        $matrixPointSize = 4;
        if (isset($qrSize)) {
            $matrixPointSize = min(max((int)$qrSize, 1), 10);
        }
        if (isset($qrData)) {
            if (trim($qrData) == '') {
                exit('数据不能为空!');
            }
            //生成文件名 文件路径+图片名字前缀+md5(名称)+.jpg
//            $filename = $PNG_TEMP_DIR . $savePrefix . md5($qrData . '|' . $errorCorrectionLevel . '|' . $matrixPointSize) . '.png';
            if($new){
                $filename = $PNG_TEMP_DIR . md5($qrData . '|' . $errorCorrectionLevel . '|' . $matrixPointSize) . '.png';
            }
            //开始生成
            \PHPQRCode\QRcode::png($qrData, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
        } else {
            //默认生成
            \PHPQRCode\QRcode::png('PHP QR Code :)', $filename, $errorCorrectionLevel, $matrixPointSize, 2);
        }
//        if (file_exists($PNG_TEMP_DIR . basename($filename))){
//            return basename($filename);
//        } else{
//            return FALSE;
//        }
        return $filename;
    }


    /**
     * 生成支付单编号(两位随机 + 从2000-01-01 00:00:00 到现在的秒数+微秒+会员ID%1000)，该值会传给第三方支付接口
     * 长度 =2位 + 10位 + 3位 + 3位  = 18位
     * 1000个会员同一微秒提订单，重复机率为1/100
     * @return string
     */
    public static function makeOrderSn($uid){
        return mt_rand(10,99)
                . sprintf('%010d',time() - 946656000)
                . sprintf('%03d', (float) microtime() * 1000)
                . sprintf('%03d', (int) $uid % 1000);
    }

    /**
     * 获取随机字符串
     * @param $len
     * @param null $chars
     * @return string
     */
    public static function getRandomStr($len, $chars=null){
        if (is_null($chars)) {
            $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        }
        mt_srand(10000000 * (double)microtime());
        for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $lc)];
        }
        return $str;
    }

    /**
     * 生成资源下载时的token
     * @param $sid
     * @return string
     */
    public static function createResourceDownloadToken($sid){
        return md5($sid.microtime().rand(0,999999));
    }
}